package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
)

// 获取租户访问令牌
func getTenantAccessToken(appID, appSecret string) (string, error) {
	url := "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal"
	data := map[string]string{
		"app_id":     appID,
		"app_secret": appSecret,
	}
	jsonData, err := json.Marshal(data)
	if err != nil {
		return "", err
	}

	req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
	if err != nil {
		return "", err
	}
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}

	var result map[string]interface{}
	err = json.Unmarshal(body, &result)
	if err != nil {
		return "", err
	}

	if result["code"].(float64) != 0 {
		return "", fmt.Errorf("获取租户访问令牌失败，错误信息: %v", result["msg"])
	}

	return result["tenant_access_token"].(string), nil
}

// 更新单元格值
func updateCellValue(accessToken, spreadsheetToken string, sheetID int, row, col int, value string) error {
	url := fmt.Sprintf("https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/%s/values/update", spreadsheetToken)
	data := map[string]interface{}{
		"value_range": map[string]interface{}{
			"sheet_id": sheetID,
			"range":    fmt.Sprintf("%s%d:%s%d", string('A'+col-1), row, string('A'+col-1), row),
			"values":   [][]interface{}{{value}},
		},
	}
	jsonData, err := json.Marshal(data)
	if err != nil {
		return err
	}

	req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Authorization", "Bearer "+accessToken)

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}

	var result map[string]interface{}
	err = json.Unmarshal(body, &result)
	if err != nil {
		return err
	}

	if result["code"].(float64) != 0 {
		return fmt.Errorf("更新单元格值失败，错误信息: %v", result["msg"])
	}

	return nil
}

// 读取单元格值
func readCellValue(accessToken, spreadsheetToken string, sheetID int, row, col int) (string, error) {
	url := fmt.Sprintf("https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/%s/values/%s%d", spreadsheetToken, string('A'+col-1), row)
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return "", err
	}
	req.Header.Set("Authorization", "Bearer "+accessToken)

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}

	var result map[string]interface{}
	err = json.Unmarshal(body, &result)
	if err != nil {
		return "", err
	}

	if result["code"].(float64) != 0 {
		return "", fmt.Errorf("读取单元格值失败，错误信息: %v", result["msg"])
	}

	valueRange, ok := result["data"].(map[string]interface{})["value_range"].(map[string]interface{})
	if !ok {
		return "", fmt.Errorf("解析响应数据失败，未找到 value_range 字段")
	}

	values, ok := valueRange["values"].([][]interface{})
	if !ok || len(values) == 0 || len(values[0]) == 0 {
		return "", nil
	}

	return fmt.Sprintf("%v", values[0][0]), nil
}

func main() {
	// 替换为你的 App ID 和 App Secret
	appID := "cli_a7375cf0067b101c"
	appSecret := "51tDwm2Zt5hZ09GPe7IGRhdWwlgFxQIa"
	// 替换为你的多维表格 spreadsheetToken
	spreadsheetToken := "C3libxfy7aRtQ2s571Rcn0NLnTg" // "your_spreadsheet_token"
	// 通常第一个 sheet 的 ID 为 0
	sheetID := 0
	// B1 格的行索引为 1，列索引为 2
	row := 1
	col := 3
	// 要设置的单元格内容
	value := "新的内容123"

	// 获取租户访问令牌
	accessToken, err := getTenantAccessToken(appID, appSecret)
	if err != nil {
		fmt.Println("获取租户访问令牌失败:", err)
		return
	}

	// 更新单元格值
	err = updateCellValue(accessToken, spreadsheetToken, sheetID, row, col, value)
	if err != nil {
		fmt.Println("更新单元格值失败:", err)
	} else {
		fmt.Println("单元格值更新成功")
	}

	// C1 格的行索引为 1，列索引为 3
	readRow := 1
	readCol := 3

	// 读取单元格值
	cellValue, err := readCellValue(accessToken, spreadsheetToken, sheetID, readRow, readCol)
	if err != nil {
		fmt.Println("读取单元格值失败:", err)
	} else {
		fmt.Printf("C1 单元格的值为: %s\n", cellValue)
	}

}
